home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / devices / msh_1_5 / part02 < prev    next >
Internet Message Format  |  1990-02-21  |  47KB

  1. Path: xanth!cs.odu.edu!Amiga-Request
  2. From: Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v90i080: MSH 1.5 - Messydos File System Handler , Part02/06
  5. Message-ID: <11499@xanth.cs.odu.edu>
  6. Date: 21 Feb 90 01:58:35 GMT
  7. Sender: tadguy@cs.odu.edu
  8. Reply-To: Olaf 'Rhialto' Seibert <U211344%HNYKUN11.BITNET@CUNYVM.CUNY.EDU>
  9. Lines: 1497
  10. Approved: tadguy@cs.odu.edu (Tad Guy)
  11. X-Mail-Submissions-To: Amiga@cs.odu.edu
  12. X-Post-Discussions-To: comp.sys.amiga
  13.  
  14. Submitted-by: Olaf 'Rhialto' Seibert <U211344%HNYKUN11.BITNET@CUNYVM.CUNY.EDU>
  15. Posting-number: Volume 90, Issue 080
  16. Archive-name: devices/msh-1.5/part02
  17.  
  18. #!/bin/sh
  19. # This is a shell archive.  Remove anything before this line, then unpack
  20. # it by saving it into a file and typing "sh file".  To overwrite existing
  21. # files, type "sh file -c".  You can also feed this as standard input via
  22. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  23. # will see the following message at the end:
  24. #        "End of archive 2 (of 6)."
  25. # Contents:  doc/dev.man.uu src/hanlock.c src/hanmain.c
  26. # Wrapped by tadguy@xanth on Tue Feb 20 20:57:08 1990
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'doc/dev.man.uu' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'doc/dev.man.uu'\"
  30. else
  31. echo shar: Extracting \"'doc/dev.man.uu'\" \(14325 characters\)
  32. sed "s/^X//" >'doc/dev.man.uu' <<'END_OF_FILE'
  33. Xbegin 664 dev.man
  34. XM"B`@("`@;65S<WED:7-K+F1E=FEC92@I("`@($%M:6=A(%!R;V=R86UM97(GW
  35. XM<R!-86YU86P@("`@(&UE<W-Y9&ES:RYD979I8V4H*0H*"@H@("`@()LQ;5-9)
  36. XM3D]04UE3(`H@("`@("`@("`@FS!M(VEN8VQU9&4@/&5X96,O:6\N:#X*("`@;
  37. XM("`@("`@("-I;F-L=61E(#QD979I8V5S+W1R86-K9&ES:RYH/@H@("`@("`@3
  38. XM("`@(VEN8VQU9&4@/&1E=BYH/@H*("`@("`@("`@($]P96Y$979I8V4H(FUEH
  39. XM<W-Y9&ES:RYD979I8V4B+"!5;FET+"!)3T5X=%1$+"!&;&%G<RD["B`@("`@J
  40. XM("`@("!"96=I;DE/*$E/17AT5$0I.PH@("`@("`@("`@0VQO<V5$979I8V4H"
  41. XM24]%>'141"D["@H@("`@()LQ;55304=%(`H@("`@("`@("`@FS!M365S<WED^
  42. XM:7-K+F1E=FEC92`@8V%N("!B92`@=7-E9"!I;G-T96%D(&]F('1R86-K9&ES!
  43. XM:RYD979I8V4N"B`@("`@("`@("!!;&P@8W5R<F5N="!T<F%C:V1I<VLN9&5V*
  44. XM:6-E(&-O;6UA;F1S(&%R92`@<W5P<&]R=&5D+B`@("!4:&4*("`@("`@("`@:
  45. XM(&]N;'D@(&9U;F-T:6]N86P@9&EF9F5R96YC92!I<R!T:&4@9F]R;6%T(&]F[
  46. XM('1H92!D:7-K+"!W:&EC:`H@("`@("`@("`@:7,@8V]M<&%T:6)L92!W:71H-
  47. XM(&UE<W-Y9&]S('-Y<W1E;7,N("`*"B`@("`@FS%M0T]-34%.1%,@"B`@("`@&
  48. XM("`@("";,&U3=7!P;W)T960@8V]M;6%N9',@87)E.B`*"B`@("`@("`@("`]3
  49. XM($--1%])3E9!3$E$("`@("`]($--1%]215-%5"`@("`@("`J($--1%]214%$&
  50. XM"B`@("`@("`@("`J($--1%]74DE412`@("`@("`J($--1%]54$1!5$4@("`@R
  51. XM("`]($--1%]#3$5!4@H@("`@("`@("`@/2!#341?4U1/4"`@("`@("`@/2!#W
  52. XM341?4U1!4E0@("`@("`@/2!#341?1DQ54T@*("`@("`@("`@("`@5$1?34]4A
  53. XM3U(@("`@("`@(#T@5$1?4T5%2R`@("`@("`@("H@5$1?1D]234%4"B`@("`@Q
  54. XM("`@("`@(%1$7U)%34]612`@("`@("`@(%1$7T-(04Y'14Y532`@("`@(%1$J
  55. XM7T-(04Y'15-4051%"B`@("`@("`@("`@(%1$7U!23U135$%455,@("`@(%1$H
  56. XM7U)!5U)%040@("`@("`@(%1$7U)!5U=2251%"B`@("`@("`@("`@(%1$7T=%>
  57. XM5$12259%5%E012`@(%1$7T=%5$Y5351204-+4R`](%1$7T%$1$-(04Y'14E.Y
  58. XM5`H@("`@("`@("`@/2!41%]214U#2$%.1T5)3E0@*B!%5$1?5U))5$4@("`@8
  59. XM("`@*B!%5$1?4D5!1`H@("`@("`@("`@("!%5$1?34]43U(@("`@("`@/2!%;
  60. XM5$1?4T5%2R`@("`@("`@*B!%5$1?1D]234%4"B`@("`@("`@("`J($541%]53
  61. XM4$1!5$4@("`@("`]($541%]#3$5!4B`@("`@("`@($541%]205=214%$"B`@:
  62. XM("`@("`@("`@($541%]205=74DE410H*("`@("`@("`@(%1H92!C;VUM86YDE
  63. XM<R!M87)K960@=VET:"`J(&%R92!H86YD;&5D(&EN(&ET<R!O=VX@9F]R;6%TY
  64. XM("!B>0H@("`@("`@("`@;65S<WED:7-K+B`@(%1H92`@8V]M;6%N9',@(&UA0
  65. XM<FME9"`@=VET:"`@/2`@87)E("!H86YD;&5D(&)Y"B`@("`@("`@("!M97-SD
  66. XM>61I<VL@:6X@=&AE('-A;64@=V%Y(&%S('1R86-K9&ES:R!S=7!P;W-E9"`@:
  67. XM:7,@('1O("!D;RX*("`@("`@("`@(%1H92`@;W1H97(@(&-O;6UA;F1S("!A`
  68. XM<F4@<V5N="!S=')A:6=H="!T:')O=6=H('1O('1R86-K9&ES:PH@("`@("`@E
  69. XM("`@86YD(&%R92!S=6)J96-T('1O(&%L;"!I=',@9FQA=W,@86YD(&9E871U,
  70. XM<F5S+B`@"@H@("`@()LQ;4]014Y$159)0T4@1DQ!1U,@"B`@("`@("`@("";9
  71. XM,&U41$9?04Q,3U=?3D].7S-?-3H@06QL;W=S(&]P96YI;F<@-#`@=')A8VL@^
  72. XM9')I=F5S+B`@26=N;W)E9"P*("`@("`@("`@('-I;F-E(&ET(&ES('1H92!DI
  73. XM969A=6QT(&)E:&%V:6]U<B!W:&EC:"!C86YN;W0@8F4@9&ES86)L960N("`*S
  74. XM"B`@("`@FS%M24\@4D5154535"!&3$%'4R`*("`@("`@("`@()LP;51H92!I=
  75. XM;U]&;&%G<R!F:65L9"!O9B!A;B!)3U-T9%)E<2!O<B!)3T5X=%1$("!S=')U>
  76. XM8W1U<F4@(&UA>0H@("`@("`@("`@8V]N=&%I;B!T:&4@9F]L;&]W:6YG(&9LD
  77. XM86=S.B`*"B`@("`@("`@("!)3T9?455)0TLZ(%1H:7,@9FQA9R!I<R!S=7!PS
  78. XM;W)T960@9F]R(&]N;'D@82!F97<@8V]M;6%N9',N("`*"B`@("`@("`@("!)'
  79. XM3U1$1E])3D1%6%-93D,Z($9O<B!%5$0O0TU$7U)!5U)%040@86YD(%]74DE4_
  80. XM12X@(`H*("`@("`@("`@($E/341&7S0P5%)!0TM3.B`@5&AI<R`@9FQA9R`@M
  81. XM:7,@(&9O<B`@151$+T--1%]214%$+"`@7U=2251%+`H@("`@("`@("`@7T9/^
  82. XM4DU!5"P@86YD(%]3145++B`@268@<V5T+"!T<F5A="!T:&4@9&ES:R!A<R`@O
  83. XM-#`@(&-Y;&EN9&5R"B`@("`@("`@("!M961I82X@("!)9B`@:70@:&%P<&5N^
  84. XM<R!T;R!B92!I;B!A;B`X,"!C>6QI;F1E<B!D<FEV92P@979E<GD*("`@("`@`
  85. XM("`@(&]T:&5R(&-Y;&EN9&5R('=I;&P@8F4@<VMI<'!E9"!T;R!U<V4@=&AE\
  86. XM('-A;64@(&-Y;&EN9&5R<R`@80H@("`@("`@("`@-#`M8WEL:6YD97(@9')I(
  87. XM=F4@('=O=6QD+B`@("!.;W)M86QL>2`@>6]U('-E="!O<B!C;&5A<B!T:&ES+
  88. XM"B`@("`@("`@("!F;&%G(&]N8V4@870@=&AE('1I;64@>6]U(')E860@=&AEH
  89. XM(&)O;W1B;&]C:R!A;F0@97AA;6EN92!I=',*("`@("`@("`@(&QA>6]U="!I:
  90. XM;F9O<FUA=&EO;BX@($ET(&ES(&=U87)A;G1E960@=&AA="`@;65S<WED:7-K1
  91. XM("!W;VXG=`H@("`@("`@("`@8VAA;F=E('1H:7,@(&9L86<N("`@($E/341&N
  92. XM7S0P5%)!0TM3("!I<R`@;F]T("!S=7!P;W)T960@9F]R"B`@("`@("`@("!%4
  93. XM5$0O5$1?4D%74D5!1"!A;F0@7U)!5U=2251%+"!S:6YC92!T:&5S92!A<F4@:
  94. XM8V]N<VED97)E9"`@=&\*"@H@("`@($MO<VUO4V]F="`@("`@("`@("`@("`@F
  95. XM("`@("`@("`@("TQ+2`@("`@("`@("`@("`@("`@("`@("!697)S:6]N(#,TX
  96. XM+C4*"@H@("`@(&UE<W-Y9&ES:RYD979I8V4H*2`@("!!;6EG82!0<F]G<F%M#
  97. XM;65R)W,@36%N=6%L("`@("!M97-S>61I<VLN9&5V:6-E*"D*"@H@("`@("`@%
  98. XM("`@8F4@(")D:6%G;F]S=&EC(B!F=6YC=&EO;G,@86YD('1H97)E9F]R92!S3
  99. XM:&]U;&0@8F4@87,@<F%W(&%S"B`@("`@("`@("!P;W-S:6)L92X@(`H*("`@B
  100. XM("";,6U$25-+($9/4DU!5"`*("`@("`@("`@()LP;51H92!D:7-K(&9O<FUA0
  101. XM="!U<V5D(&ES(&-O;7!A=&EB;&4@('=I=&@@(&UE<W-Y9&]S("!S>7-T96US,
  102. XM+@H@("`@("`@("`@0F]T:"`T,"`@86YD("`X,"`@8WEL:6YD97(@(&UE9&EA^
  103. XM("!A<F4@<W5P<&]R=&5D+B`@5&AE<F4@87)E"B`@("`@("`@("!N;W)M86QL[
  104. XM>2`Y('-E8W1O<G,@<&5R('1R86-K(&%N9"!T=V\@('1R86-K<R`@<&5R("!C0
  105. XM>6QI;F1E<BX*("`@("`@("`@("A/=71D871E9"D@('-I;F=L92US:61E9"`@R
  106. XM9&ES:W,@(&-A;B`@;VYL>2`@8F4@(')E860@(&EF('1H90H@("`@("`@("`@O
  107. XM9')I=FEN9R`@<V]F='=A<F4@(&ES("!P<F5P87)E9"`@=&\@('1R96%T("!T$
  108. XM:&5M("!A<R`@;F]R;6%L"B`@("`@("`@("!D;W5B;&4M<VED960@9&ES:W,L\
  109. XM(&%N9"!S:VEP('1H92!S:61E<R!T:&%T(&%R92!N;W0@86-T=6%L;'D*("`@&
  110. XM("`@("`@('!R97-E;G0N("!/;B!T:&4@;W1H97(@:&%N9"P@=&AE(&YU;6)EN
  111. XM<B!O9B!S96-T;W)S('!E<B!T<F%C:PH@("`@("`@("`@;6%Y('9A<GD@9G)O`
  112. XM;2`X('1O(#$P+B!)9B!T:&4@;G5M8F5R(&]F('-E8W1O<G,@:7,@9&EF9F5RT
  113. XM96YT"B`@("`@("`@("!F<F]M("!T:&4@(&1E9F%U;'0@=F%L=64@*#DI+"!T2
  114. XM:&5N('1R86-K(#`@;VX@<VED92`P(&UU<W0@8F4*("`@("`@("`@(')E860@H
  115. XM9FER<W0@8F5F;W)E('1H:7,@:7,@<F5C;V=N:7IE9"X@($ET("!I<R`@=&AEA
  116. XM;B`@87-S=6UE9`H@("`@("`@("`@=&AA="`@86QL("!T<F%C:W,@;VX@=&AEZ
  117. XM(&5N=&ER92!D:7-K(&AA=F4@=&AE('-A;64@;G5M8F5R(&]F"B`@("`@("`@%
  118. XM("!S96-T;W)S+B`@4V\L(&%L;"!P;W-I=&EO;B!C86QC=6QA=&EO;G,@(&%R"
  119. XM92`@8F%S960@(&]N("!T:&4*("`@("`@("`@(&QA>6]U="!O9B!T:&4@=F5RM
  120. XM>2!F:7)S="!T<F%C:RX@(`H*("`@("`@("`@("TM+2!);F1E>"!P=6QS92`@@
  121. XM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+@H@("`@("`@L
  122. XM("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@@
  123. XM("`@("`@("`@("!\"B`@("`@("`@("`@("`@-C`@*B`D-&4@("`@1T%0(#$@\
  124. XM("`H)#DR-30@96YC;V1E9"D@("`@("`@("`@("`@('P*("`@("`@("`@("`@!
  125. XM("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@@
  126. XM("`@("`@?`H@("`@("`@("`@+2TM($9I<G-T(%-E8W1O<B`M+2TM+2TM+2TMG
  127. XM+2TM+2TM+2TM+2TM+2TM+2TM+2X@("`@("!\"B`@("`@("`@("`@("`@("`@K
  128. XM("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@?"`@("`@\
  129. XM('P*("`@("`@("`@("`@("`Q,B`J("0P,"`@("!'05`@,B`@("@D04%!02!E6
  130. XM;F-O9&5D*2`@("`@("!\("`@("`@?`H@("`@("`@("`@('P@("`S("H@)&$Q'
  131. XM("`@(%-93D,@("`@*"0T-#@Y(&5N8V]D960I("`@("`@('P@("`@("!\"B`@?
  132. XM("`@("`@("`@?"`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@\
  133. XM("`@("`@("`@?"`@("`@('P*("`@("`@("`@("!\("`@,2`J("1F92`@("!)Q
  134. XM1"U!9&1R97-S($UA<FL@("`M+B`H)#4U-30I("!\("`@("`@?`H@("`@("`@G
  135. XM("`@('P@('1R86-K("`@("`@("`@("`@("`@("`@("`@("`@("!\("`@("`@-
  136. XM("`@('P@("`@("!\"B`@("`@("`@("`@?"`@<VED92`@("`@("`@("`@("`@#
  137. XM("`@("`@("`@("`@('P@("`@("`@("`@?"`@("`@('P*("`@("`@("`@("!\Z
  138. XM("!S96-T;W(@("`@("`@("`@("`@("`@("`@("`@("`@(#X@240@("`@("!\W
  139. XM("`@("`@?`H@("`@("`@("`@('P@(&QE;F=T:"`H,#TQ,C@L,3TR-38L,CTU[
  140. XM,3(@971C+BE\("!&:65L9"`@('P@(%,@("!\"B`@("`@("`@("`@+3X@0U)#.
  141. XM(#$@("`@("`@("`@("`@("`@("`@("`@("`@('P@("`@("`@("`@?"`@92`@N
  142. XM('P@(%0*("`@("`@("`@("`M/B!#4D,@,B`@("`@("`@("`@("`@("`@("`@/
  143. XM("`@("`M)R`@("`@("`@("!\("!C("`@?"`@<@H@("`@("`@("`@("`@("`@K
  144. XM("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`^('0@2
  145. XM("`@/B!A"B`@("`@("`@("`@("`@,C(@*B`D-&4@("`@1T%0(#$@("`H)#DRT
  146. XM-30@96YC;V1E9"D@("`@("`@?"`@;R`@('P@(&,*("`@("`@("`@("`@("`Q)
  147. XM,B`J("0P,"`@("!'05`@,B`@("@D04%!02!E;F-O9&5D*2`@("`@("!\("!RC
  148. XM("`@?"`@:PH@("`@("`@("`@('P@("`S("H@)&$Q("`@(%-93D,@("`@*"0T=
  149. XM-#@Y(&5N8V]D960I("`@("`@('P@("`@("!\"B`@("`@("`@("`@?"`@("`@>
  150. XM("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@?"`@("`@\
  151. XM('P*("`@("`@("`@("!\("`@,2`J("1F8B`@("!$051!+4%D<F5S<R!-87)K]
  152. XM("`M+B`H)#4U-#4I("!\("`@("`@?`H@("`@("`@("`@('P@(#4Q,B!B>71E-
  153. XM<R!D871A("`@("`@("`@("`@("`@("`@/B!$051!("`@('P@("`@("!\"B`@G
  154. XM("`@("`@("`@+3X@0U)#(#$@("`@("`@("`@("`@("`@("`@("`@("`@('P@P
  155. XM($9I96QD("`@?"`@("`@('P*("`@("`@("`@("`M/B!#4D,@,B`@("`@("`@[
  156. XM("`@("`@("`@("`@("`@("`M)R`@("`@("`@("!\("`@("`@?`H@("`@("`@6
  157. XM("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@@
  158. XM("`@('P@("`@("!\"B`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@"
  159. XM("`@("`@("`@("`@("`@("`@("`@("`@?"`@("`@('P*("`@("`@("`@("`@"
  160. XM("`X,"`J("0T92`@("!'05`@,R`@("@D.3(U-"!E;F-O9&5D*2`@("`@("!\Q
  161. XM("`@("`@?`H@("`@("`@("`@+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM%
  162. XM+2TM+2TM+2TM+2TM+2TM+2TM+2<@("`@("!\"B`@("`@("`@("`@("`@("`@D
  163. XM("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@@
  164. XM('P*("`@("`@("`@("`N+BXN+BX@."!M;W)E('-E8W1O<G,@+BXN+BXN+B`@*
  165. XM("`@("`@("`@("`@("`@("`@("`@?`H@("`@("`@("`@("`@("`@("`@("`@F
  166. XM("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("!\"B`@F
  167. XM("`@("`@("`@("`@<F5S="`@)#1E("`@("`@("`@("`H)#DR-30@96YC;V1E)
  168. XM9"D@("`@("`@("`@("`@('P*("`@("`@("`@("TM+2TM+2TM+2TM+2TM+2TM0
  169. XM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM)PH*("`@("";*
  170. XM,6U$159)051)3TY3(`H@("`@("`@("`@FS!M5&AE(%1$7U)%34-(04Y'14E./
  171. XM5"!C;VUM86YD('=O<FMS+B`@*$ET(&1O97-N)W0@=VET:"!T:&4@,2XR"B`@(
  172. XM("`@("`@("!O<B`Q+C,@=')A8VMD:7-K+F1E=FEC92DN("`*"@H*"B`@("`@Z
  173. XM2V]S;6]3;V9T("`@("`@("`@("`@("`@("`@("`@("`@+3(M("`@("`@("`@1
  174. XM("`@("`@("`@("`@(%9E<G-I;VX@,S0N-0H*"B`@("`@;65S<WED:7-K+F1E!
  175. XM=FEC92@I("`@($%M:6=A(%!R;V=R86UM97(G<R!-86YU86P@("`@(&UE<W-Y\
  176. XM9&ES:RYD979I8V4H*0H*"B`@("`@("`@("!4:&4@("!M97-S>61I<VL@("!5*
  177. XM;FET("`@<W1R=6-T=7)E("`@9&]E<R`@(&YO="`@(&QO;VL@(&QI:V4*("`@\
  178. XM("`@("`@(%1$55]0=6)L:6-5;FET(&%T(&%L;"X@(`H*("`@("`@("`@($ENR
  179. XM('-O;64@<VET=6%T:6]N<RP@97)R;W(@<F5T=7)N<R!M87D@8F4@9&EF9F5R.
  180. XM96YT("!O<B`@;&5S<PH@("`@("`@("`@<W!E8VEF:6,N("`*"B`@("`@("`@Q
  181. XM("!$871A("!B=69F97)S("!T;R!B92!R96%D(&]R('=R:71T96X@8W5R<F5N*
  182. XM=&QY(&1O;B=T(&YE960@=&\*("`@("`@("`@(&)E(&EN($-H:7`@;65M;W)YY
  183. XM+B`@5&AI<R!M:6=H="!C:&%N9V4@:6X@=&AE("!F=71U<F4N("`@($9O<@H@W
  184. XM("`@("`@("`@9G5T=7)E("!C;VUP871I8FEL:71Y("!A;F0@('=I=&@@('1H`
  185. XM92`@=')A8VMD:7-K+F1E=FEC92`@>6]U"B`@("`@("`@("!S:&]U;&0@;F]TJ
  186. XM(&1E<&5N9"!O;B!T:&ES+B`@"@H@("`@("`@("`@26X@;W)D97(@=&\@8F4@D
  187. XM86)L92!T;R!F;W)M870@82`@=')A8VL@('=I=&@@(&$@(&YO;G-T86YD87)D/
  188. XM"B`@("`@("`@("!N=6UB97(@;V8@<V5C=&]R<R`H9G)O;2`X('1O(#$P*2P@X
  189. XM>6]U(&UU<W0@=7-E('1H92!41%]&3U)-050*("`@("`@("`@(&-O;6UA;F0@]
  190. XM('=I=&@@(&QE<W,@=&AA;B`T,"!S96-T;W)S("@R,#0X,"!B>71E<RD@870@0
  191. XM82!T:6UE+@H@("`@("`@("`@4VEN8V4@>6]U(&UU<W0@86QW87ES(&9O<FUAF
  192. XM="!E;G1I<F4@=')A8VMS(&%T(&$@('1I;64L("!T:&ES"B`@("`@("`@("!U+
  193. XM;FEQ=65L>2`@9&5T97)M:6YE<R`@=&AE(&YU;6)E<B!O9B!S96-T;W)S('EO!
  194. XM=2!W86YT(&]N(&5A8V@*("`@("`@("`@('1R86-K+B`@5&AE(&-U<G)E;G0@N
  195. XM;G5M8F5R(&]F('-E8W1O<G,@<&5R('1R86-K+"!W:&EC:"`@=VEL;`H@("`@>
  196. XM("`@("`@8F4@('5S960@(&QA=&5R("!W:&5N(')E861I;F<@9G)O;2!T:&4@1
  197. XM<V%M92!D:7-K+"!I<R!U<&1A=&5D"B`@("`@("`@("!A8V-O<F1I;F=L>2X@'
  198. XM("!)9B`@>6]U("`@<W!E8VEF>2`@(#0P("`@<V5C=&]R<R`@(&]R("`@;6]RU
  199. XM92P*("`@("`@("`@(&UE<W-Y9&ES:RYD979I8V4@9&]E<R!N;W0@871T96UP\
  200. XM="!T;R!G=65S<R!W:&%T('EO=2!W86YT(&)U=`H@("`@("`@("`@<VEM<&QY\
  201. XM('5S97,@('1H92`@=F%L=64@('1H870@('=A<R!A;')E861Y('-E="X@(%-O8
  202. XM+"!Y;W4@;6%Y"B`@("`@("`@("!C:&]O<V4@=&\@9FER<W0@(&9O<FUA="`@O
  203. XM82`@<VEN9VQE("!T<F%C:R`@=&\@(&EN9&EC871E("!T:&4*("`@("`@("`@'
  204. XM(&1E<VER960@(&YU;6)E<B`@;V8@('-E8W1O<G,@<&5R('1R86-K+"!A;F0@<
  205. XM=&AE;B!I;B!O;F4@8V%L;`H@("`@("`@("`@9F]R;6%T('1H92!E;G1I<F4@_
  206. XM<F5S="!O9B!T:&4@9&ES:RX@(`H*("`@("`@("`@(%=H96X@82!D:7-K('=I_
  207. XM=&@@;6]R92!O<B!L97-S('1H86X@.2!S96-T;W)S("!P97(@('1R86-K("!I3
  208. XM<PH@("`@("`@("`@<F5A9"P@('EO=2!M=7-T(&9I<G-T(&ES<W5E(&$@0TU$1
  209. XM7U)%040@8V]M;6%N9"!F;W(@=&AE(&9I<G-T"B`@("`@("`@("!S96-T;W(H,
  210. XM<RD@;V8@('1H92`@(&1I<VLN("`@("`@5VAE;B`@('1R86-K("`@,"`@(&ES>
  211. XM("`@<F5A9"P*("`@("`@("`@(&UE<W-Y9&ES:RYD979I8V4@(&1E=&5R;6EN$
  212. XM97,@:&]W(&UA;GD@<V5C=&]R<R!T:&5R92!A<F4@;VX@80H@("`@("`@("`@6
  213. XM=')A8VLN("!4:&ES(&YU;6)E<B!I<R!T:&5N('5S960@869T97)W87)D<R!W*
  214. XM:&5N(&-A;&-U;&%T:6YG"B`@("`@("`@("!T:&4@=')A8VMS(&%N9"!S:61EM
  215. XM<R!O9B!O=&AE<B!S96-T;W)S+B`@(%-O+"`@=&AI<R`@:7,@('9E<GD*("`@-
  216. XM("`@("`@(&EM<&]R=&%N="X@($)U="!F;W(@=&AO<V4@*'9I<G1U86QL>2!I^
  217. XM;7!O<W-I8FQE*2!C87-E<R!W:&5R90H@("`@("`@("`@;F]T("!A;&P@=')A<
  218. XM8VMS(&AA=F4@=&AE('-A;64@;G5M8F5R(&]F('-E8W1O<G,L(&%L;"!S96-T!
  219. XM;W)S"B`@("`@("`@("!T:&%T("!W97)E("!R96%D("!O;B`@86YY("!T<F%CM
  220. XM:R`@=VEL;"`@8F4@("!W<FET=&5N("`@8F%C:RX*("`@("`@("`@($9O<G1U0
  221. XM;F%T96QY+"`@(&%L;"`@8W5R<F5N=&QY("!K;F]W;B`@9FEL92`@<WES=&5ML
  222. XM<R`@:&%V92`@80H@("`@("`@("`@8F]O=&)L;V-K("!A="`@=')A8VL@(#`L'
  223. XM("!S:61E("`P+"`@('-O("`@=&AE>2`@(&%L;"`@(&%D87!T"B`@("`@("`@J
  224. XM("!T<F%N<W!A<F5N=&QY+B`@"@H@("`@()LQ;4-!5D5!5%,@"B`@("`@("`@C
  225. XM("";,&U4:&4@*&]U=&1A=&5D*2!41%]214U/5D4@8V]M;6%N9"!I<R!R;W5TN
  226. XM960@=&\@=')A8VMD:7-K+B`@07,*("`@("`@("`@(&$@(')E<W5L="!O9B!TA
  227. XM:&ES+"!O;FQY(&]N92!D:7-K(')E;6]V92!I;G1E<G)U<'0@*'!E<B!U;FETI
  228. XM*0H@("`@("`@("`@;6%Y("!B92`@:6YS=&%L;&5D("`H=VET:"`@=&AI<R`@=
  229. XM8V]M;6%N9"DL("!W:&5T:&5R("!T:')O=6=H"B`@("`@("`@("!T<F%C:V1I8
  230. XM<VL@;W(@(&UE<W-Y9&ES:RX@("`@*%1H:7,@('-E96US("!T;R`@:&%V92`@-
  231. XM8F5E;B!T:&4*("`@("`@("`@(&]R:6=I;F%L("!I;G1E;G1I;VX@(&]F("!4;
  232. XM1%]214U/5D4N*2`@3V8@("!C;W5R<V4L("`@8W5R<F5N=`H@("`@("`@("`@'
  233. XM<')O9W)A;7,@<VAO=6QD('5S92!41%]!1$1#2$%.1T5)3E0N("`*"B`@("`@:
  234. XMFS%M551)3$E42453(`H@("`@("`@("`@FS!M02`@<V5P87)A=&4@('!R;V=R7
  235. XM86T@(&-A;&QE9"`@26=N;W)E("!I<R!S=7!P;&EE9"P@=VAI8V@@;6%Y"B`@)
  236. XM("`@("`@("!S=7!P<F5S<R!T:&4@0U)#(&-H96-K(&EN(&%N>2!C=7)R96YT^
  237. XM;'D@;W!E;B!U;FET+B`@5VAE;B!T:&4*("`@("`@("`@('5N:70@:7,@9&5F-
  238. XM:6YI=&EV96QY(&-L;W-E9"!A;F0@;&%T97(@<F5O<&5N960L(&EG;F]R:6YG=
  239. XM($-20PH@("`@("`@("`@;6ES;6%T8VAE<R!A9V%I;B!H87,@:71S(&1E9F%U!
  240. XM;'0@=F%L=64@;V8@3F\N("`*"B`@("`@("`@("!5<V%G93H@:6=N;W)E(#QU5
  241. XM;FET;G(^(#Q915,O3D\^"@H@("`@("`@("`@268@>6]U(&]N;'D@9VEV92!T!
  242. XM:&4@=6YI="!N=6UB97(L(&EG;F]R92!W:6QL(&]U='!U="`@96ET:&5R"B`@:
  243. XM("`@("`@("!997,@(&]R("!.;RP@<F5F;&5C=&EN9R!W:&5T:&5R($-20R!M:
  244. XM:7-M871C:&5S(&-U<G)E;G1L>2!A<F4*("`@("`@("`@(&EG;F]R960N("`*+
  245. XM"@H*("`@("!+;W-M;U-O9G0@("`@("`@("`@("`@("`@("`@("`@("`M,RT@0
  246. XM("`@("`@("`@("`@("`@("`@("`@5F5R<VEO;B`S-"XU"@H*("`@("!M97-SF
  247. XM>61I<VLN9&5V:6-E*"D@("`@06UI9V$@4')O9W)A;6UE<B=S($UA;G5A;"`@&
  248. XM("`@;65S<WED:7-K+F1E=FEC92@I"@H*("`@("`@("`@(%1H:7,@<')O9W)A,
  249. XM;2!C86X@8F4@=7-E9G5L('=H96X@>6]U("!W:7-H("!T;R`@<F5C;W9E<B`@]
  250. XM9&%T80H@("`@("`@("`@9G)O;2!A("!D86UA9V5D("!O<B!M87)G:6YA;"!DL
  251. XM:7-K+B`@4V]M971I;65S('1E>'0@9FEL97,@;6%Y"B`@("`@("`@("!B92!U0
  252. XM<V%B;&4@979E;B!I9B!T:&5R92!A<F4@82!F97<@97)R;W)S(&EN('1H96TNG
  253. XM("`*"B`@("`@FS%M05542$]24R`*("`@("`@("`@()LP;4UE<W-Y9&ES:R!IZ
  254. XM<R!W<FET=&5N(&)Y()LS;5-O=7)C97)E<B";,&U/;&%F()LS;5)H:6%L=&\@8
  255. XMFS!M4V5I8F5R="X@(%1H90H@("`@("`@("`@;&]W+6QE=F5L("`@=W)I=&ENS
  256. XM9R`@<&%R="`@=V%S("!O<FEG:6YA;&QY("!D;VYE("!B>2`@5V5R;F5R"B`@A
  257. XM("`@("`@("!'_&YT:&5R+B!5<V5D('=I=&@@<&5R;6ES<VEO;BX@(`H*"@H*H
  258. XM"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"
  259. XM"@H*("`@("!+;W-M;U-O9G0@("`@("`@("`@("`@("`@("`@("`@("`M-"T@1
  260. XC("`@("`@("`@("`@("`@("`@("`@5F5R<VEO;B`S-"XU"@H@D
  261. X``
  262. Xend
  263. Xsize 10205
  264. END_OF_FILE
  265. if test 14325 -ne `wc -c <'doc/dev.man.uu'`; then
  266.     echo shar: \"'doc/dev.man.uu'\" unpacked with wrong size!
  267. fi
  268. # end of 'doc/dev.man.uu'
  269. fi
  270. if test -f 'src/hanlock.c' -a "${1}" != "-c" ; then 
  271.   echo shar: Will not clobber existing file \"'src/hanlock.c'\"
  272. else
  273. echo shar: Extracting \"'src/hanlock.c'\" \(17870 characters\)
  274. sed "s/^X//" >'src/hanlock.c' <<'END_OF_FILE'
  275. X/*-
  276. X * $Id: hanlock.c,v 1.4 90/01/27 20:22:17 Rhialto Exp $
  277. X * $Log:    hanlock.c,v $
  278. X * Revision 1.4  90/01/27  20:22:17  Rhialto
  279. X * Added extra check when freeing MSFileLocks.
  280. X * 
  281. X * Revision 1.3  90/01/23  00:36:57  Rhialto
  282. X * Add an #ifndef READONLY.
  283. X *
  284. X * Revision 1.2  89/12/17  23:05:33  Rhialto
  285. X * Add MSSetProtect
  286. X *
  287. X * Revision 1.1  89/12/17  20:03:01  Rhialto
  288. X *
  289. X * HANLOCK.C
  290. X *
  291. X * The code for the messydos file system handler
  292. X *
  293. X * The Lock department. Takes care of operations on locks, and consequently,
  294. X * on directories.
  295. X *
  296. X * This code is (C) Copyright 1989 by Olaf Seibert. All rights reserved. May
  297. X * not be used or copied without a licence.
  298. X-*/
  299. X
  300. X#include "han.h"
  301. X#include "dos.h"
  302. X
  303. X#ifdef DEBUG
  304. X#   define    debug(x)  dbprintf x
  305. X#else
  306. X#   define    debug(x)
  307. X#endif
  308. X
  309. Xstruct LockList *LockList;    /* List of all locked files we have. Note
  310. X                 * this is not the same as all locks we
  311. X                 * have */
  312. Xstruct MSFileLock *RootLock;    /* Lock on root directory */
  313. Xstruct MSFileLock *EmptyFileLock;    /* 2nd result of MSLock() */
  314. X
  315. Xstruct DirEntry FakeRootDirEntry = {
  316. X    {                /* de_Msd */
  317. X    "Unnamed ",             /* msd_Name */
  318. X    "   ",                  /* msd_Ext */
  319. X    ATTR_VOLUMELABEL,    /* msd_Attributes */
  320. X    {0},            /* msd_Pad1 */
  321. X    0,            /* msd_Time */
  322. X    0x21,            /* msd_Date, 1/1/80 */
  323. X    0,            /* msd_Cluster */
  324. X    0            /* msd_Filesize */
  325. X    },
  326. X    -1,             /* de_Sector */
  327. X    0                /* de_Offset */
  328. X};
  329. Xbyte        DotDot[1 + 8 + 3] = "..          ";
  330. X
  331. X/*
  332. X * This routine compares a name in a directory entry with a given name
  333. X */
  334. X
  335. Xint
  336. XCompareNames(dir, name)
  337. Xregister struct MsDirEntry *dir;
  338. Xregister byte  *name;
  339. X{
  340. X#ifdef DEBUG
  341. X    if (name[0] == '\\') {
  342. X    extern short    DBEnable;
  343. X
  344. X    DBEnable = name[1] & 0x0F;
  345. X
  346. X    return CMP_END_OF_DIR;
  347. X    }
  348. X#endif
  349. X
  350. X    if (dir->msd_Name[0] & DIR_DELETED_MASK)
  351. X    return CMP_FREE_SLOT;
  352. X
  353. X    if (dir->msd_Name[0] == 0)
  354. X    return CMP_END_OF_DIR;    /* end of directory */
  355. X
  356. X    if (dir->msd_Attributes & ATTR_VOLUMELABEL)
  357. X    return CMP_NOT_EQUAL;
  358. X
  359. X    if (strncmp(dir->msd_Name, name, 8 + 3))
  360. X    return CMP_NOT_EQUAL;
  361. X
  362. X    if (dir->msd_Attributes & ATTR_DIRECTORY)
  363. X    return CMP_OK_DIR;
  364. X
  365. X    return CMP_OK_FILE;
  366. X}
  367. X
  368. Xvoid
  369. XNextDirEntry(sector, offset)
  370. Xregister word  *sector;
  371. Xregister word  *offset;
  372. X{
  373. X    if ((*offset += MS_DIRENTSIZE) >= Disk.bps) {
  374. X    *offset = 0;
  375. X    if (*sector >= Disk.datablock) {
  376. X        /* Must be subdirectory */
  377. X        *sector = NextClusteredSector(*sector);
  378. X        debug(("NextClusteredSector: %d\n", *sector));
  379. X    } else {
  380. X        if (++*sector >= Disk.datablock) {
  381. X        *sector = SEC_EOF;
  382. X        }
  383. X    }
  384. X    }
  385. X    /* else no more work needed */
  386. X}
  387. X
  388. X/*
  389. X * Get the directory entry following the given one. If requested, we make
  390. X * the directory longer.
  391. X */
  392. X
  393. Xstruct DirEntry *
  394. XFindNext(previous, createit)
  395. Xregister struct DirEntry *previous;
  396. Xint        createit;
  397. X{
  398. X    byte       *sector;
  399. X    word        prevsec = previous->de_Sector;
  400. X
  401. X    NextDirEntry(&previous->de_Sector, &previous->de_Offset);
  402. X
  403. X    if (previous->de_Sector == SEC_EOF) {
  404. X    error = ERROR_OBJECT_NOT_FOUND;
  405. X#ifndef READONLY
  406. X    if (createit) {
  407. X        if (prevsec < Disk.datablock - 1) { /* Should not be necessary */
  408. X        previous->de_Sector = prevsec + 1;
  409. X        } else if (prevsec >= Disk.datablock) {
  410. X        previous->de_Sector = FindFreeSector(prevsec);
  411. X        }
  412. X        if (previous->de_Sector != SEC_EOF) {
  413. X        sector = EmptySec(previous->de_Sector);
  414. X        setmem(sector, (int) Disk.bps, 0);
  415. X        MarkSecDirty(sector);
  416. X        FreeSec(sector);
  417. X        setmem(&previous->de_Msd, sizeof (previous->de_Msd), 0);
  418. X
  419. X        return previous;
  420. X        }
  421. X    }
  422. X#endif
  423. X    } else if (sector = GetSec(previous->de_Sector)) {
  424. X    CopyMem(sector + previous->de_Offset, &previous->de_Msd,
  425. X        (long) MS_DIRENTSIZE);
  426. X    OtherEndianMsd(&previous->de_Msd);
  427. X    FreeSec(sector);
  428. X
  429. X    return previous;
  430. X    }
  431. X    return NULL;
  432. X}
  433. X
  434. X#ifdef DEBUG
  435. X
  436. Xvoid
  437. XPrintDirEntry(de)
  438. Xstruct DirEntry *de;
  439. X{
  440. X    debug(("%d,%d ", de->de_Sector, de->de_Offset));
  441. X    debug(("%.8s.%.3s attr:%x time:%x date:%x start:%x size:%lx\n",
  442. X       de->de_Msd.msd_Name,
  443. X       de->de_Msd.msd_Ext,
  444. X       de->de_Msd.msd_Attributes,
  445. X       de->de_Msd.msd_Time,
  446. X       de->de_Msd.msd_Date,
  447. X       de->de_Msd.msd_Cluster,
  448. X       de->de_Msd.msd_Filesize
  449. X       ));
  450. X}
  451. X
  452. X#endif
  453. X
  454. X/*
  455. X * MakeLock makes a struct MSFileLock from a directory entry and the
  456. X * parent directory MSFileLock pointer. It looks if it already has a Lock
  457. X * on it. In that case, it simply increments its reference count, when
  458. X * possible.
  459. X */
  460. X
  461. Xstruct MSFileLock *
  462. XMakeLock(parentdir, dir, mode)
  463. Xstruct MSFileLock *parentdir;
  464. Xstruct DirEntry *dir;
  465. Xulong        mode;
  466. X{
  467. X    register struct MSFileLock *fl;
  468. X    struct MSFileLock *nextfl;
  469. X
  470. X    if (mode != EXCLUSIVE_LOCK || (dir->de_Msd.msd_Attributes & ATTR_DIR))
  471. X    mode = SHARED_LOCK;
  472. X
  473. X#ifdef DEBUG
  474. X    debug(("MakeLock: "));
  475. X    PrintDirEntry(dir);
  476. X#endif
  477. X
  478. X    /*
  479. X     * Look through our list to see if we already have it. The criteria
  480. X     * for this are: 1. the directory entries are the same or 2. they have
  481. X     * the same first cluster and are both directories (which can have
  482. X     * multiple directory entries). Sigh.
  483. X     */
  484. X
  485. X    for (fl = (struct MSFileLock *) LockList->ll_List.mlh_Head;
  486. X     nextfl = (struct MSFileLock *) fl->msfl_Node.mln_Succ;
  487. X     fl = nextfl) {
  488. X#ifdef DEBUG
  489. X    debug(("> "));
  490. X    PrintDirEntry(&fl->msfl_Msd);
  491. X#endif
  492. X    if ((fl->msfl_DirSector == dir->de_Sector &&
  493. X         fl->msfl_DirOffset == dir->de_Offset) ||
  494. X        (fl->msfl_Msd.msd_Cluster == dir->de_Msd.msd_Cluster &&
  495. X         (dir->de_Msd.msd_Attributes & ATTR_DIR) &&
  496. X         (fl->msfl_Msd.msd_Attributes & ATTR_DIR))
  497. X        ) {
  498. X        /* Found existing lock on file */
  499. X        if (fl->msfl_Refcount < 0 || mode == EXCLUSIVE_LOCK) {
  500. X        error = ERROR_OBJECT_IN_USE;
  501. X        return NULL;
  502. X        }
  503. X        fl->msfl_Refcount++;
  504. X        return fl;
  505. X    }
  506. X    }
  507. X
  508. X    fl = AllocMem((long) sizeof (*fl), MEMF_PUBLIC);
  509. X    if (fl == NULL) {
  510. X    error = ERROR_NO_FREE_STORE;
  511. X    return NULL;
  512. X    }
  513. X    fl->msfl_Parent = parentdir ? MSDupLock(parentdir) : NULL;
  514. X
  515. X    fl->msfl_Refcount = (mode == EXCLUSIVE_LOCK) ? -1 : 1;
  516. X    fl->msfl_DirSector = dir->de_Sector;
  517. X    fl->msfl_DirOffset = dir->de_Offset;
  518. X    fl->msfl_Msd = dir->de_Msd;
  519. X
  520. X    AddHead(&LockList->ll_List, fl);
  521. X
  522. X    return fl;
  523. X}
  524. X
  525. X/*
  526. X * This routine Locks a file. It first searches it in the directory, then
  527. X * lets the rest of the work be done by MakeLock(). If it encounters an
  528. X * empty slot in the directory, it remembers where, in case we need it. If
  529. X * you clear the MODE_CREATEFILE bit in the mode parameter, we fabricate a
  530. X * new MSFileLock from the empty directory entry. It then becomes the
  531. X * caller's responsibility to MSUnLock() it eventually.
  532. X */
  533. X
  534. Xstruct MSFileLock *
  535. XMSLock(parentdir, name, mode)
  536. Xstruct MSFileLock *parentdir;
  537. Xbyte           *name;
  538. Xulong        mode;
  539. X{
  540. X    byte       *sector;
  541. X    struct MSFileLock *newlock;
  542. X    register struct DirEntry *de;
  543. X    struct DirEntry sde;
  544. X    byte       *nextpart;
  545. X    byte        component[8 + 3];    /* Note: not null-terminated */
  546. X    int         createit;
  547. X    word        freesec;
  548. X    word        freeoffset;
  549. X
  550. X    de = &sde;
  551. X    newlock = NULL;
  552. X
  553. X    /*
  554. X     * See if we have an absolute path name (starting at the root).
  555. X     */
  556. X
  557. X    {
  558. X    register byte  *colon;
  559. X
  560. X    if (colon = index(name, ':')) {
  561. X        name = colon + 1;
  562. X        parentdir = RootLock;
  563. X    }
  564. X    }
  565. X
  566. X    /*
  567. X     * Get a copy of the parent dir lock, so we can walk it over the
  568. X     * directory tree.
  569. X     */
  570. X    parentdir = MSDupLock(parentdir);
  571. X
  572. X    /*
  573. X     * Start with the directory entry of the parent dir.
  574. X     */
  575. X
  576. X    sde.de_Msd = parentdir->msfl_Msd;
  577. X    sde.de_Sector = parentdir->msfl_DirSector;
  578. X    sde.de_Offset = parentdir->msfl_DirOffset;
  579. X#ifdef DEBUG
  580. X    debug(("pdir %08lx: ", parentdir));
  581. X    PrintDirEntry(&parentdir->msfl_Msd);
  582. X#endif
  583. X
  584. Xnewdir:
  585. X    freesec = SEC_EOF;        /* Means none found yet */
  586. X
  587. X    nextpart = ToMSName(component, name);
  588. X    debug(("Component: '%11s'\n", component));
  589. X    if (nextpart[0] != '/') {
  590. X    nextpart = NULL;
  591. X#ifndef READONLY
  592. X    /*
  593. X     * See if we are requested to get an empty spot in the directory
  594. X     * if the given name does not exist already. The value of mode is
  595. X     * not important until we actually create the filelock.
  596. X     */
  597. X    if (!(mode & MODE_CREATEFILE)) {
  598. X        mode ^= MODE_CREATEFILE;
  599. X        createit = 1;
  600. X    } else
  601. X        createit = 0;
  602. X#endif
  603. X    } else
  604. X    nextpart++;
  605. X
  606. X    /*
  607. X     * Are we at the end of the name? Then we are finished now. This works
  608. X     * because sde contains the directory entry of parentdir.
  609. X     */
  610. X
  611. X    if (name[0] == '\0')
  612. X    goto exit;
  613. X
  614. X    /*
  615. X     * If there is more name, we enter the directory, and here we get the
  616. X     * first entry.
  617. X     */
  618. X
  619. X    sde.de_Sector = DirClusterToSector(sde.de_Msd.msd_Cluster);
  620. X    sde.de_Offset = 0;
  621. X
  622. X    if ((sector = GetSec(sde.de_Sector)) == NULL)
  623. X    goto error;
  624. X
  625. X    CopyMem(sector, &sde.de_Msd, (long) sizeof (struct MsDirEntry));
  626. X    OtherEndianMsd(&sde.de_Msd);
  627. X    FreeSec(sector);
  628. X
  629. X    while (de) {
  630. X    switch (CompareNames(&sde.de_Msd, component)) {
  631. X    case CMP_FREE_SLOT:
  632. X        if (freesec == SEC_EOF) {
  633. X        freesec = sde.de_Sector;
  634. X        freeoffset = sde.de_Offset;
  635. X        }
  636. X        /* Fall through */
  637. X    case CMP_NOT_EQUAL:
  638. X        de = FindNext(&sde, createit);      /* Try next directory
  639. X                         * entry */
  640. X        continue;
  641. X    case CMP_OK_DIR:
  642. X        if (name = nextpart) {
  643. X        /*
  644. X         * We want to keep locks on all directories between each
  645. X         * bottom directory and file lock, so we can easily find
  646. X         * the parent of a lock. There just seems to be a problem
  647. X         * here when we enter the 'subdirectories' . or .. , but
  648. X         * that in not so: MakeLock will detect that it has
  649. X         * already a lock on those, and NOT make :one/two the
  650. X         * parent of :one/two/.. .
  651. X         */
  652. X        newlock = MakeLock(parentdir, de, SHARED_LOCK);
  653. X        MSUnLock(parentdir);
  654. X        parentdir = newlock;
  655. X        goto newdir;
  656. X        }
  657. X        goto exit;
  658. X    case CMP_OK_FILE:
  659. X        if (nextpart) {
  660. X        error = ERROR_OBJECT_WRONG_TYPE;
  661. X        de = NULL;
  662. X        }
  663. X        goto exit;
  664. X    case CMP_END_OF_DIR:    /* means we will never find it */
  665. X        error = ERROR_OBJECT_NOT_FOUND;
  666. X        if (freesec == SEC_EOF) {
  667. X        freesec = sde.de_Sector;
  668. X        freeoffset = sde.de_Offset;
  669. X        }
  670. X        de = NULL;
  671. X        goto exit;
  672. X    }
  673. X    }
  674. X
  675. Xexit:
  676. X    if (de) {
  677. X    newlock = MakeLock(parentdir, &sde, mode);
  678. X    } else {
  679. X    newlock = NULL;
  680. X#ifndef READONLY
  681. X    if (createit &&         /* Do we want to make it? */
  682. X        error == ERROR_OBJECT_NOT_FOUND &&    /* does it not exist yet? */
  683. X        nextpart == NULL) { /* do we have the last part of the name */
  684. X        if (freesec != SEC_EOF) {   /* is there any room? */
  685. X        if (IDDiskState == ID_VALIDATED) {
  686. X            error = 0;
  687. X            setmem(&sde.de_Msd, sizeof (sde.de_Msd), 0);
  688. X            sde.de_Sector = freesec;
  689. X            sde.de_Offset = freeoffset;
  690. X            /* ToMSName(sde.de_Msd.msd_Name, name); */
  691. X            strncpy(sde.de_Msd.msd_Name, component, 8 + 3);
  692. X            EmptyFileLock = MakeLock(parentdir, &sde, mode);
  693. X            WriteFileLock(EmptyFileLock);
  694. X        } else
  695. X            error = ERROR_DISK_WRITE_PROTECTED;
  696. X        } else
  697. X        error = ERROR_DISK_FULL;
  698. X    }
  699. X#endif
  700. X    }
  701. X
  702. Xerror:
  703. X    MSUnLock(parentdir);
  704. X
  705. X    return newlock;
  706. X}
  707. X
  708. X/*
  709. X * This routine DupLocks a file. This simply means incrementing the
  710. X * reference count, if it was not an exclusive Lock.
  711. X */
  712. X
  713. Xstruct MSFileLock *
  714. XMSDupLock(fl)
  715. Xstruct MSFileLock *fl;
  716. X{
  717. X    if (fl == NULL)
  718. X    fl = RootLock;
  719. X    if (fl->msfl_Refcount <= 0) {
  720. X    error = ERROR_OBJECT_IN_USE;
  721. X    return NULL;
  722. X    } else {
  723. X    fl->msfl_Refcount++;
  724. X    }
  725. X
  726. X    return fl;
  727. X}
  728. X
  729. X/*
  730. X * This routine DupLocks the parent of a lock, if there is one.
  731. X */
  732. X
  733. Xstruct MSFileLock *
  734. XMSParentDir(fl)
  735. Xregister struct MSFileLock *fl;
  736. X{
  737. X    if (fl == NULL || fl == RootLock) {
  738. X    error = ERROR_OBJECT_NOT_FOUND;
  739. X    } else if (fl->msfl_Parent)
  740. X    return MSDupLock(fl->msfl_Parent);
  741. X
  742. X    return NULL;
  743. X}
  744. X
  745. X/*
  746. X * This routine UnLocks a file.
  747. X */
  748. X
  749. Xint
  750. XMSUnLock(fl)
  751. Xstruct MSFileLock *fl;
  752. X{
  753. X#ifdef DEBUG
  754. X    debug(("MSUnLock %08lx: ", fl));
  755. X    PrintDirEntry(&fl->msfl_Msd);
  756. X#endif
  757. X
  758. X    if (fl) {
  759. X    if (--fl->msfl_Refcount <= 0) {
  760. X        struct LockList *list;
  761. X
  762. X        list = (struct LockList *) fl->msfl_Node.mln_Pred;
  763. X        Remove(fl);
  764. X        debug(("Remove()d %08lx\n", fl));
  765. X
  766. X        /*
  767. X         * We may need to get rid of the LockList if it is empty. This
  768. X         * is the current LockList iff we are called from
  769. X         * MSDiskRemoved(). Please note that we are not even sure that
  770. X         * 'list' really is the list header, therefore the careful
  771. X         * test if fl refers to a volume label (root lock) which is
  772. X         * finally UnLock()ed. Because of the recursion, we only try to
  773. X         * free the LockList iff there is no parent anymore, since
  774. X         * otherwise list may be invalid by the time we use it.
  775. X         */
  776. X        if (fl->msfl_Parent) {
  777. X        MSUnLock(fl->msfl_Parent);
  778. X        } else {
  779. X        if ((fl->msfl_Msd.msd_Attributes & ATTR_VOLUMELABEL) &&
  780. X            ((void *) list->ll_List.mlh_Head ==
  781. X             (void *) &list->ll_List.mlh_Tail)
  782. X            ) {
  783. X            FreeLockList(list);
  784. X        }
  785. X        }
  786. X        FreeMem(fl, (long) sizeof (*fl));
  787. X    }
  788. X    }
  789. X    return DOSTRUE;
  790. X}
  791. X
  792. X/*
  793. X * This is (among other things) the inverse of ToMSName().
  794. X */
  795. X
  796. Xvoid
  797. XExamineDirEntry(msd, fib)
  798. Xstruct MsDirEntry *msd;
  799. Xregister struct FileInfoBlock *fib;
  800. X{
  801. X    register byte  *end,
  802. X           *dot;
  803. X
  804. X#ifdef DEBUG
  805. X    debug(("+ "));
  806. X    PrintDirEntry(msd);
  807. X#endif
  808. X    strncpy(&fib->fib_FileName[1], msd->msd_Name, 8);
  809. X    /* Keep at least one character, even a space, before the dot */
  810. X    dot = ZapSpaces(&fib->fib_FileName[2], &fib->fib_FileName[1 + 8]);
  811. X    dot[0] = ' ';
  812. X    strncpy(dot + 1, msd->msd_Ext, 3);
  813. X    dot[4] = '\0';
  814. X    end = ZapSpaces(dot, dot + 4);
  815. X    if (end > dot)
  816. X    dot[0] = '.';
  817. X    fib->fib_FileName[0] = strlen(&fib->fib_FileName[1]);
  818. X
  819. X    fib->fib_DirEntryType =
  820. X    (msd->msd_Attributes & ATTR_DIR) ? FILE_DIR : FILE_FILE;
  821. X    fib->fib_Protection = 0;
  822. X    if (!(msd->msd_Attributes & ATTR_ARCHIVED))
  823. X    fib->fib_Protection |= FIBF_ARCHIVE;
  824. X    if (msd->msd_Attributes & ATTR_READONLY)
  825. X    fib->fib_Protection |= (FIBF_WRITE | FIBF_DELETE);
  826. X    if (msd->msd_Attributes & (ATTR_HIDDEN|ATTR_SYSTEM))
  827. X    fib->fib_Protection |= FIBF_HIDDEN;
  828. X    fib->fib_Size = msd->msd_Filesize;
  829. X    fib->fib_NumBlocks = (msd->msd_Filesize + Disk.bps - 1) / Disk.bps;
  830. X    ToDateStamp(&fib->fib_Date, msd->msd_Date, msd->msd_Time);
  831. X    fib->fib_Comment[0] = 0;
  832. X}
  833. X
  834. Xint
  835. XMSExamine(fl, fib)
  836. Xstruct MSFileLock *fl;
  837. Xregister struct FileInfoBlock *fib;
  838. X{
  839. X    if (fl == NULL)
  840. X    fl = RootLock;
  841. X
  842. X    fib->fib_DiskKey = ((ulong) fl->msfl_DirSector << 16) | fl->msfl_DirOffset;
  843. X    fib->fib_EntryType = 0;    /* No ExNext called yet */
  844. X    ExamineDirEntry(&fl->msfl_Msd, fib);
  845. X
  846. X    return DOSTRUE;
  847. X}
  848. X
  849. Xint
  850. XMSExNext(fl, fib)
  851. Xstruct MSFileLock *fl;
  852. Xregister struct FileInfoBlock *fib;
  853. X{
  854. X    word        sector = fib->fib_DiskKey >> 16;
  855. X    word        offset = (word) fib->fib_DiskKey;
  856. X    byte       *buf;
  857. X
  858. X    if (fl == NULL)
  859. X    fl = RootLock;
  860. X
  861. X    if (fib->fib_EntryType == 0) {
  862. X    fib->fib_EntryType = 1;
  863. X    if (fl->msfl_Msd.msd_Attributes & ATTR_DIR) {
  864. X        /* Enter subdirectory */
  865. X        sector = DirClusterToSector(fl->msfl_Msd.msd_Cluster);
  866. X        offset = 0;
  867. X    } else
  868. X        NextDirEntry(§or, &offset);
  869. X    } else {
  870. Xskip:
  871. X    NextDirEntry(§or, &offset);
  872. X    }
  873. X
  874. X    if (sector != SEC_EOF) {
  875. X    register struct MsDirEntry *msd;
  876. X
  877. X    if (buf = GetSec(sector)) {
  878. X        msd = (struct MsDirEntry *) (buf + offset);
  879. X        if (msd->msd_Name[0] == '\0') {
  880. X        FreeSec(buf);
  881. X        goto end;
  882. X        }
  883. X        if (msd->msd_Name[0] & DIR_DELETED_MASK ||
  884. X        msd->msd_Name[0] == '.' ||      /* Hide "." and ".." */
  885. X        (msd->msd_Attributes & ATTR_VOLUMELABEL)) {
  886. X        FreeSec(buf);
  887. X        goto skip;
  888. X        }
  889. X        OtherEndianMsd(msd);/* Get correct endianness */
  890. X        fib->fib_DiskKey = ((ulong) sector << 16) | offset;
  891. X        ExamineDirEntry(msd, fib);
  892. X        OtherEndianMsd(msd);/* Get wrong endianness */
  893. X        FreeSec(buf);
  894. X
  895. X        return DOSTRUE;
  896. X    }
  897. X    }
  898. Xend:
  899. X    error = ERROR_NO_MORE_ENTRIES;
  900. X    return DOSFALSE;
  901. X}
  902. X
  903. X/*
  904. X * Convert AmigaDOS protection bits to messy attribute bits.
  905. X */
  906. X
  907. Xlong
  908. XMSSetProtect(parentdir, name, mask)
  909. Xregister struct MSFileLock *parentdir;
  910. Xchar       *name;
  911. Xlong       mask;
  912. X{
  913. X    register struct MSFileLock *lock;
  914. X
  915. X    if (parentdir == NULL)
  916. X    parentdir = RootLock;
  917. X
  918. X    lock = MSLock(parentdir, name, EXCLUSIVE_LOCK);
  919. X    if (lock) {
  920. X    /* Leave SYSTEM bit as-is */
  921. X    lock->msfl_Msd.msd_Attributes &= ATTR_SYSTEM;
  922. X    /* write or delete protected -> READONLY */
  923. X    if (mask & (FIBF_WRITE|FIBF_DELETE))
  924. X        lock->msfl_Msd.msd_Attributes |= (ATTR_READONLY);
  925. X    /* hidden -> hidden */
  926. X    if (mask & FIBF_HIDDEN)
  927. X        lock->msfl_Msd.msd_Attributes |= (ATTR_HIDDEN);
  928. X    /* archived=0 (default) -> archived=1 (default) */
  929. X    if (!(mask & FIBF_ARCHIVE))
  930. X        lock->msfl_Msd.msd_Attributes |= (ATTR_ARCHIVED);
  931. X    WriteFileLock(lock);
  932. X    MSUnLock(lock);
  933. X    return TRUE;
  934. X    }
  935. X
  936. X    return FALSE;
  937. X}
  938. X
  939. Xint
  940. XCheckLock(lock)
  941. Xregister struct MSFileLock *lock;
  942. X{
  943. X    register struct MSFileLock *parent;
  944. X
  945. X    if (lock) {
  946. X    while (parent = lock->msfl_Parent)
  947. X        lock = parent;
  948. X    if (lock != RootLock)
  949. X        error = ERROR_DEVICE_NOT_MOUNTED;
  950. X    }
  951. X    return error;
  952. X}
  953. X
  954. X#ifndef READONLY
  955. X
  956. Xvoid
  957. XWriteFileLock(fl)
  958. Xregister struct MSFileLock *fl;
  959. X{
  960. X    debug(("WriteFileLock %08lx\n", fl));
  961. X
  962. X    if (fl) {
  963. X    register byte  *block = GetSec(fl->msfl_DirSector);
  964. X
  965. X    if (block) {
  966. X        CopyMem(&fl->msfl_Msd, block + fl->msfl_DirOffset,
  967. X            (long) sizeof (fl->msfl_Msd));
  968. X        OtherEndianMsd(block + fl->msfl_DirOffset);
  969. X        MarkSecDirty(block);
  970. X        FreeSec(block);
  971. X    }
  972. X    }
  973. X}
  974. X
  975. Xvoid
  976. XUpdateFileLock(fl)
  977. Xregister struct MSFileLock *fl;
  978. X{
  979. X    struct DateStamp dateStamp;
  980. X
  981. X    debug(("UpdateFileLock %08lx\n", fl));
  982. X
  983. X    DateStamp(&dateStamp);
  984. X    ToMSDate(&fl->msfl_Msd.msd_Date, &fl->msfl_Msd.msd_Time, &dateStamp);
  985. X    WriteFileLock(fl);
  986. X}
  987. X
  988. X#endif
  989. X
  990. Xstruct LockList *
  991. XNewLockList(cookie)
  992. Xvoid           *cookie;
  993. X{
  994. X    struct LockList *ll;
  995. X
  996. X    if (ll = AllocMem((long) sizeof (*ll), MEMF_PUBLIC)) {
  997. X    NewList(&ll->ll_List);
  998. X    ll->ll_Cookie = cookie;
  999. X    } else
  1000. X    error = ERROR_NO_FREE_STORE;
  1001. X
  1002. X    return ll;
  1003. X}
  1004. X
  1005. Xvoid
  1006. XFreeLockList(ll)
  1007. Xstruct LockList *ll;
  1008. X{
  1009. X    debug(("FreeLockList %08lx\n", ll));
  1010. X
  1011. X    if (ll) {
  1012. X    MayFreeVolNode(ll->ll_Cookie);  /* not too happy about this */
  1013. X    FreeMem(ll, (long) sizeof (*ll));
  1014. X    if (ll == LockList)     /* locks on current volume */
  1015. X        LockList = NULL;
  1016. X    }
  1017. X}
  1018. END_OF_FILE
  1019. if test 17870 -ne `wc -c <'src/hanlock.c'`; then
  1020.     echo shar: \"'src/hanlock.c'\" unpacked with wrong size!
  1021. fi
  1022. # end of 'src/hanlock.c'
  1023. fi
  1024. if test -f 'src/hanmain.c' -a "${1}" != "-c" ; then 
  1025.   echo shar: Will not clobber existing file \"'src/hanmain.c'\"
  1026. else
  1027. echo shar: Extracting \"'src/hanmain.c'\" \(10114 characters\)
  1028. sed "s/^X//" >'src/hanmain.c' <<'END_OF_FILE'
  1029. X/*-
  1030. X * $Id: hanmain.c,v 1.4 90/01/27 20:13:00 Rhialto Exp $
  1031. X * $Log:    hanmain.c,v $
  1032. X * Revision 1.4  90/01/27  20:13:00  Rhialto
  1033. X * *** empty log message ***
  1034. X * 
  1035. X * Revision 1.3  89/12/17  21:29:51  Rhialto
  1036. X * *** empty log message ***
  1037. X *
  1038. X * Revision 1.1  89/12/17  20:02:31  Rhialto
  1039. X * Initial revision
  1040. X *
  1041. X *
  1042. X *  HANMAIN.C
  1043. X *
  1044. X *  The code for the messydos file system handler.
  1045. X *
  1046. X *  Some start/stop stuff that is not really part of the
  1047. X *  file system itself but that must be done anyway.
  1048. X *
  1049. X *  This code is (C) Copyright 1989 by Olaf Seibert. All rights reserved. May
  1050. X *  not be used or copied without a licence.
  1051. X-*/
  1052. X
  1053. X#include "han.h"
  1054. X#include "dos.h"
  1055. X
  1056. X#ifdef DEBUG
  1057. X#   define    debug(x)  dbprintf x
  1058. X#else
  1059. X#   define    debug(x)
  1060. X#endif
  1061. X
  1062. Xextern char    DotDot[1 + 8 + 3];
  1063. Xstruct Library *IntuitionBase;
  1064. Xstatic char RCSId[] = "Messydos filing system $Revision: 1.4 $ $Date: 90/01/27 20:13:00 $, by Olaf Seibert";
  1065. X
  1066. Xbyte
  1067. XToUpper(ch)
  1068. Xregister byte    ch;
  1069. X{
  1070. X    if (ch >= 'a' && ch <= 'z')
  1071. X    return ch + ('A' - 'a');
  1072. X    if (ch == '.')
  1073. X    return '!';
  1074. X    return ch & ~DIR_DELETED_MASK;
  1075. X}
  1076. X
  1077. Xlong
  1078. Xlmin(a, b)
  1079. Xlong        a,
  1080. X        b;
  1081. X{
  1082. X    return (a < b) ? a : b;
  1083. X}
  1084. X
  1085. Xbyte           *
  1086. XZapSpaces(begin, end)
  1087. Xregister byte  *begin,
  1088. X           *end;
  1089. X{
  1090. X    while (end > begin && end[-1] == ' ')
  1091. X    *--end = '\0';
  1092. X
  1093. X    return end;
  1094. X}
  1095. X
  1096. X/*
  1097. X * Map an arbitrary file name to MS-DOS conventions. The output format is
  1098. X * 8+3 without dot, padded with spaces, suitable for direct comparison
  1099. X * with directory entries. Return a pointer to the delimiter found ('\0'
  1100. X * or '/'). [[Make sure that Examine/ExNext return a proper inverse of
  1101. X * this...]]
  1102. X */
  1103. X
  1104. Xbyte           *
  1105. XToMSName(dest, source)
  1106. Xbyte           *dest;
  1107. Xregister byte  *source;
  1108. X{
  1109. X    byte       *dotp;
  1110. X    byte       *slashp;
  1111. X    register int    i,
  1112. X            len;
  1113. X
  1114. X    if (*source == '/') {       /* parentdir */
  1115. X    strncpy(dest, DotDot, 8 + 3);   /* ".." */
  1116. X    return source;
  1117. X    }
  1118. X    /*
  1119. X     * Remove any strictly leading dots. .info -> info, .indent.pro ->
  1120. X     * indent.pro, .profile -> profile, etc.
  1121. X     */
  1122. X    while (*source == '.')
  1123. X    source++;
  1124. X
  1125. X    /*
  1126. X     * Find dot and slash which are delimiters of name and extension.
  1127. X     */
  1128. X    {
  1129. X    register byte  *cp;
  1130. X
  1131. X    cp = source;
  1132. X    while (*cp) {
  1133. X        if (*cp == '.' || *cp == '/')
  1134. X        break;
  1135. X        cp++;
  1136. X    }
  1137. X    dotp = cp;
  1138. X    while (*cp) {
  1139. X        if (*cp == '/')
  1140. X        break;
  1141. X        cp++;
  1142. X    }
  1143. X    slashp = cp;
  1144. X    }
  1145. X
  1146. X    len = dotp - source;
  1147. X    if (len > 8)
  1148. X    len = 8;
  1149. X
  1150. X    for (i = 0; i < len; i++) {
  1151. X    *dest++ = ToUpper(*source++);
  1152. X    }
  1153. X    for (; i < 8; i++) {
  1154. X    *dest++ = ' ';
  1155. X    }
  1156. X
  1157. X    source = dotp + 1;
  1158. X    len = slashp - source;    /* so will be -1 if no suffix */
  1159. X    if (len > 3)
  1160. X    len = 3;
  1161. X
  1162. X    for (i = 0; i < len; i++) {
  1163. X    *dest++ = ToUpper(*source++);
  1164. X    }
  1165. X    for (; i < 3; i++) {
  1166. X    *dest++ = ' ';
  1167. X    }
  1168. X
  1169. X    return slashp;
  1170. X}
  1171. X
  1172. X/*
  1173. X * Do the Info call.
  1174. X */
  1175. X
  1176. Xlong
  1177. XMSDiskInfo(infodata)
  1178. Xstruct InfoData *infodata;
  1179. X{
  1180. X    extern DEVLIST *VolNode;
  1181. X
  1182. X    setmem(infodata, sizeof (*infodata), 0);
  1183. X
  1184. X    infodata->id_DiskState = IDDiskState;
  1185. X    infodata->id_DiskType = IDDiskType;
  1186. X    infodata->id_UnitNumber = UnitNr;
  1187. X
  1188. X    infodata->id_VolumeNode = (BPTR) CTOB(VolNode);
  1189. X    infodata->id_InUse = LockList ? 1 : 0;
  1190. X
  1191. X    if (IDDiskType == ID_DOS_DISK) {
  1192. X    infodata->id_NumBlocks = Disk.nsects;
  1193. X    infodata->id_NumBlocksUsed = Disk.nsects - Disk.nsectsfree;
  1194. X    infodata->id_BytesPerBlock = Disk.bps;
  1195. X    }
  1196. X    return DOSTRUE;
  1197. X}
  1198. X
  1199. X/*
  1200. X * We (re-)establish our List of MSFileLocks after a disk has been
  1201. X * (re-)inserted. If there are no known locks, we make the root lock from
  1202. X * the volume label, if there is one.
  1203. X *
  1204. X * We get a special cookie to hand to a cleanup routine that we must call
  1205. X * when finally all locks on the current disk are UnLock()ed. (this is
  1206. X * actually the volume node, but we don't want to know that.)
  1207. X *
  1208. X * This must be called some time after IdentifyDisk().
  1209. X */
  1210. X
  1211. Xvoid
  1212. XMSDiskInserted(locks, cookie)
  1213. Xregister struct LockList **locks;
  1214. Xvoid           *cookie;
  1215. X{
  1216. X    debug(("MSDiskInserted %08lx\n", cookie));
  1217. X
  1218. X    LockList = *locks;
  1219. X
  1220. X    if (LockList == NULL) {
  1221. X    LockList = NewLockList(cookie);
  1222. X    RootLock = MakeLock(NULL, &Disk.vollabel, SHARED_LOCK);
  1223. X    } else {
  1224. X    RootLock = MSDupLock(GetTail(&LockList->ll_List));
  1225. X    }
  1226. X
  1227. X    InitCacheList();
  1228. X}
  1229. X
  1230. X/*
  1231. X * Remove the current disk. A place is offered to save the current
  1232. X * LockList to restore later. We must unlock the root lock since it isn't
  1233. X * a real reference to the disk, just a placeholder for dummies that hand
  1234. X * us NULL locks.
  1235. X */
  1236. X
  1237. Xint
  1238. XMSDiskRemoved(locks)
  1239. Xregister struct LockList **locks;
  1240. X{
  1241. X#ifndef READONLY
  1242. X    if (FatDirty || (DelayState & DELAY_DIRTY))
  1243. X    MSUpdate(1);            /* Force a requester */
  1244. X#endif
  1245. X
  1246. X    FreeFat();
  1247. X    FreeCacheList();
  1248. X
  1249. X    IDDiskType = ID_NO_DISK_PRESENT;
  1250. X    *locks = NULL;
  1251. X
  1252. X    if (RootLock == NULL) {
  1253. X    debug(("MSDiskRemoved with no RootLock\n"));
  1254. X    return 1;
  1255. X    }
  1256. X#ifdef DEBUG
  1257. X    if (RootLock != GetTail(&LockList->ll_List)) {
  1258. X    debug(("RootLock not at end of LockList!\n"));
  1259. X    /* Get the lock on the root dir at the tail of the List */
  1260. X    Remove(RootLock);
  1261. X    AddTail(&LockList->ll_List, RootLock);
  1262. X    }
  1263. X#endif
  1264. X
  1265. X    /*
  1266. X     * If there are no real locks on the disk, we need not keep any
  1267. X     * information about it.
  1268. X     */
  1269. X
  1270. X    MSUnLock(RootLock);         /* may call FreeLockList and free VolNode
  1271. X                 * (!) */
  1272. X    RootLock = NULL;
  1273. X
  1274. X    if (LockList) {
  1275. X    *locks = LockList;    /* VolNode can't be gone now... */
  1276. X    LockList = NULL;
  1277. X    return 0;        /* not all references gone */
  1278. X    } else {
  1279. X    return 1;        /* all gone, even the VolNode */
  1280. X    }
  1281. X}
  1282. X
  1283. Xvoid
  1284. XHanCloseDown()
  1285. X{
  1286. X#ifdef DEBUG
  1287. X    register struct MSFileLock *fl;
  1288. X
  1289. X    while (LockList && (fl = (struct MSFileLock *) GetHead(&LockList->ll_List))) {
  1290. X    debug(("UNLOCKING %08lx: ", fl));
  1291. X    PrintDirEntry(&fl->msfl_Msd);
  1292. X    MSUnLock(fl);           /* Remove()s it from this List */
  1293. X    }
  1294. X#endif
  1295. X    if (DiskIOReq) {
  1296. X    if (DiskIOReq->iotd_Req.io_Unit) {
  1297. X        MSUpdate(1);
  1298. X        CloseDevice(DiskIOReq);
  1299. X    }
  1300. X    DeleteExtIO(DiskIOReq);
  1301. X    DiskIOReq = NULL;
  1302. X    }
  1303. X    if (TimeIOReq) {
  1304. X    if (TimeIOReq->tr_node.io_Unit) {
  1305. X        WaitIO(TimeIOReq);
  1306. X        CloseDevice(TimeIOReq);
  1307. X    }
  1308. X    DeleteExtIO(TimeIOReq);
  1309. X    TimeIOReq = NULL;
  1310. X    }
  1311. X    if (DiskReplyPort) {
  1312. X    DeletePort(DiskReplyPort);
  1313. X    DiskReplyPort = NULL;
  1314. X    }
  1315. X    if (IntuitionBase) {
  1316. X    CloseLibrary(IntuitionBase);
  1317. X    IntuitionBase = NULL;
  1318. X    }
  1319. X}
  1320. X
  1321. Xint
  1322. XHanOpenUp()
  1323. X{
  1324. X    LockList = NULL;
  1325. X    RootLock = NULL;
  1326. X    Fat = NULL;
  1327. X    IDDiskState = ID_WRITE_PROTECTED;
  1328. X    IDDiskType = ID_NO_DISK_PRESENT;
  1329. X    DelayState = DELAY_OFF;
  1330. X    Disk.bps = MS_BPS;
  1331. X    InitCacheList();
  1332. X
  1333. X    TimeIOReq = NULL;
  1334. X
  1335. X#ifdef DEBUG
  1336. X    if (!(DiskReplyPort = CreatePort("MSH:disk.replyport", -1L)))
  1337. X    goto abort;
  1338. X#else
  1339. X    if (!(DiskReplyPort = CreatePort(NULL, -1L)))
  1340. X    goto abort;
  1341. X#endif
  1342. X
  1343. X    debug(("DiskReplyPort = 0x%08lx\n", DiskReplyPort));
  1344. X
  1345. X    if (!(DiskIOReq = CreateExtIO(DiskReplyPort, (long) sizeof (*DiskIOReq)))) {
  1346. X    debug(("Failed to CreateExtIO\n"));
  1347. X    goto abort;
  1348. X    }
  1349. X    if (OpenDevice(DevName, UnitNr, DiskIOReq, DevFlags | TDF_ALLOW_NON_3_5)) {
  1350. X    debug(("Failed to OpenDevice\n"));
  1351. X    goto abort;
  1352. X    }
  1353. X    TimeIOReq = (struct timerequest *) CreateExtIO(DiskReplyPort,
  1354. X                         (long) sizeof (*TimeIOReq));
  1355. X
  1356. X    if (TimeIOReq == NULL || OpenDevice(TIMERNAME, UNIT_VBLANK, TimeIOReq, 0L))
  1357. X    goto abort;
  1358. X    TimeIOReq->tr_node.io_Flags = IOF_QUICK;    /* For the first WaitIO() */
  1359. X
  1360. X    IntuitionBase = OpenLibrary("intuition.library", 0L);
  1361. X    return DOSTRUE;
  1362. X
  1363. Xabort:
  1364. X    HanCloseDown();
  1365. X    return 0;
  1366. X}
  1367. X
  1368. X/*
  1369. X * Relabel the disk. We create new labels if necessary.
  1370. X */
  1371. X
  1372. Xlong
  1373. XMSRelabel(newname)
  1374. Xbyte           *newname;
  1375. X{
  1376. X#ifdef READONLY
  1377. X    return DOSFALSE;
  1378. X#else
  1379. X    /*
  1380. X     * A null or empty string means: remove the label, if any.
  1381. X     */
  1382. X    if (!newname || !*newname) {
  1383. X    if ((int) RootLock->msfl_DirSector >= (int) Disk.rootdir) {
  1384. X        RootLock->msfl_Msd.msd_Name[0] = DIR_DELETED;
  1385. X        RootLock->msfl_Msd.msd_Attributes = 0;
  1386. X        WriteFileLock(RootLock);
  1387. X        RootLock->msfl_Msd = FakeRootDirEntry.de_Msd;
  1388. X        RootLock->msfl_DirSector = -1;
  1389. X        Disk.vollabel = FakeRootDirEntry;
  1390. X    }
  1391. X    return DOSTRUE;
  1392. X    }
  1393. X    /*
  1394. X     * No label yet? Then we must create one, even if we need to move
  1395. X     * something else for it.
  1396. X     */
  1397. X
  1398. X    if ((int) RootLock->msfl_DirSector < 0) {
  1399. X    struct MSFileLock *new;
  1400. X
  1401. X    new = MSLock(RootLock, "><>.\\", EXCLUSIVE_LOCK ^ MODE_CREATEFILE);
  1402. X    if ((new == NULL) && (new = EmptyFileLock)) {
  1403. X        error = 0;
  1404. X        if (new->msfl_DirSector == Disk.rootdir) {
  1405. X        RootLock->msfl_DirSector = Disk.rootdir;
  1406. X        RootLock->msfl_DirOffset = new->msfl_DirOffset;
  1407. X        } else {
  1408. X        /*
  1409. X         * Move something out of the first directory block. Try
  1410. X         * not to move system files or directories (. ..), but
  1411. X         * we'll do it if we need to. Set the root dir date to
  1412. X         * now.
  1413. X         */
  1414. X        byte           *fromsec;
  1415. X        byte           *tosec;
  1416. X        register struct MsDirEntry *dir;
  1417. X
  1418. X        fromsec = GetSec(Disk.rootdir);
  1419. X        tosec = GetSec(new->msfl_DirSector);
  1420. X
  1421. X        dir = (struct MsDirEntry *) fromsec;
  1422. X        while (dir->msd_Attributes & (ATTR_SYSTEM | ATTR_DIRECTORY)) {
  1423. X            if ((byte *) ++dir >= fromsec + Disk.bps) {
  1424. X            --dir;    /* Back to last entry in the block */
  1425. X            break;    /* and move it no matter what */
  1426. X            }
  1427. X        }
  1428. X        CopyMem(dir, tosec + new->msfl_DirOffset,
  1429. X            (long) sizeof (struct MsDirEntry));
  1430. X        MarkSecDirty(tosec);
  1431. X        RootLock->msfl_DirSector = Disk.rootdir;
  1432. X        RootLock->msfl_DirOffset = (byte *) dir - fromsec;
  1433. X
  1434. X        FreeSec(tosec);
  1435. X        FreeSec(fromsec);
  1436. X
  1437. X        }
  1438. X    }
  1439. X    EmptyFileLock = NULL;
  1440. X    MSUnLock(new);
  1441. X    }
  1442. X    if ((int) RootLock->msfl_DirSector >= Disk.rootdir) {
  1443. X    struct DateStamp dateStamp;
  1444. X
  1445. X    /*
  1446. X     * The easy part: Copy the name to Disk.vollabel and RootLock.
  1447. X     */
  1448. X    {
  1449. X        register int    i;
  1450. X        register byte  *s,
  1451. X               *d;
  1452. X
  1453. X        s = newname;
  1454. X        d = Disk.vollabel.de_Msd.msd_Name;
  1455. X        for (i = 0; i < 8 + 3; i++) {
  1456. X        if (s[0])
  1457. X            *d++ = ToUpper(*s++);
  1458. X        else
  1459. X            *d++ = ' ';
  1460. X        }
  1461. X    }
  1462. X    DateStamp(&dateStamp);
  1463. X    ToMSDate(&Disk.vollabel.de_Msd.msd_Date,
  1464. X         &Disk.vollabel.de_Msd.msd_Time, &dateStamp);
  1465. X    RootLock->msfl_Msd = Disk.vollabel.de_Msd;    /* Just for the name and
  1466. X                             * date */
  1467. X    WriteFileLock(RootLock);
  1468. X
  1469. X    return DOSTRUE;
  1470. X    }
  1471. X    return DOSFALSE;
  1472. X#endif
  1473. X}
  1474. X
  1475. X#ifdef DEBUG
  1476. X
  1477. X_abort()
  1478. X{
  1479. X    HanCloseDown();
  1480. X    RemTask(NULL);
  1481. X}
  1482. X
  1483. X#endif                /* DEBUG */
  1484. END_OF_FILE
  1485. if test 10114 -ne `wc -c <'src/hanmain.c'`; then
  1486.     echo shar: \"'src/hanmain.c'\" unpacked with wrong size!
  1487. fi
  1488. # end of 'src/hanmain.c'
  1489. fi
  1490. echo shar: End of archive 2 \(of 6\).
  1491. cp /dev/null ark2isdone
  1492. MISSING=""
  1493. for I in 1 2 3 4 5 6 ; do
  1494.     if test ! -f ark${I}isdone ; then
  1495.     MISSING="${MISSING} ${I}"
  1496.     fi
  1497. done
  1498. if test "${MISSING}" = "" ; then
  1499.     echo You have unpacked all 6 archives.
  1500.     rm -f ark[1-9]isdone
  1501. else
  1502.     echo You still need to unpack the following archives:
  1503.     echo "        " ${MISSING}
  1504. fi
  1505. ##  End of shell archive.
  1506. exit 0
  1507. -- 
  1508. Mail submissions (sources or binaries) to <amiga@cs.odu.edu>.
  1509. Mail comments to the moderator at <amiga-request@cs.odu.edu>.
  1510. Post requests for sources, and general discussion to comp.sys.amiga.
  1511.